﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using MLSharp;
using MLSharp.Clustering;
using MLSharp.Utilities;

namespace KnowledgeFrontierMiner
{
	/// <summary>
	/// Interaction logic for ClusterProbabilityList.xaml
	/// </summary>
	public partial class ClusterProbabilityList : UserControl
	{
		/// <summary>
		/// Designer-generated.
		/// </summary>
		public ClusterProbabilityList()
		{
			InitializeComponent();
		}

		/// <summary>
		/// Binds the data to the control.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
		{
			//Clear the old values
			ProbabilityPanel.Children.Clear();

			KnowledgeFrontierView view = (KnowledgeFrontierView) e.NewValue;

			//If the new value is null, don't do anything.
			if (view == null)
			{
				return;
			}

			IProbabilisticClusterNode node = (IProbabilisticClusterNode)view.Original;

			IDataSet ds = view.DataSet;

			//Grab probabilities out of the node
			AttributeStats[] stats = node.GetStats();

			//Loop through and create att->prob pairs and att->stddev pairs.
			//The left-half is the friendly representation, the right-half is a normalized score
			//so that stddev and probabilities are treated similarly.
			List<Pair<string, double>> values = new List<Pair<string, double>>();

			for (int i =0 ; i < stats.Length; i++)
			{
				//Skip the accuracy attribute
				if (i == view.AccuracyIndex)
				{
					continue;
				}

				//Calculate stddev and means for numeric attributes.
				if (ds.Attributes[i].IsNumeric())
				{
					stats[i].NumericStats.CalculateDerived();

					string label = string.Format("{0}: {1:G4} [{2:G4}]", ds.Attributes[i].Name,
					                             stats[i].NumericStats.Mean, stats[i].NumericStats.StdDev);

					values.Add(new Pair<string, double>(label, 1 - stats[i].NumericStats.StdDev));
				}
				else
				{
					for (int j = 0; j < ds.Attributes[i].PossibleValues.Length; j++)
					{
						double probability = stats[i].NominalCounts[j]/(double) stats[i].TotalCount;

						//If the probability is zero, don't show it.
						if (probability == 0)
						{
							continue;
						}

						string label = string.Format("P({0}={1}): {2:G4}", ds.Attributes[i].Name,
						                             ds.Attributes[i].PossibleValues[j], probability);

						values.Add(new Pair<string, double>(label, probability));
					}
				}
			}

			//We want to sort in descending order, so the comparison is reversed.
			values.Sort((p1, p2) => p2.Right.CompareTo(p1.Right));

			//Add the values to the panel
			foreach (var pair in values)
			{
				ProbabilityPanel.Children.Add(new TextBlock {Text = pair.Left});
			}
		}
	}
}
